package cn.lystudio.rohmtimeopwide_background_v11.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ConcurrentHashSet;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.lystudio.rohmtimeopwide_background_v11.entity.dto.MachineDTO;
import cn.lystudio.rohmtimeopwide_background_v11.entity.dto.PlanOutputDTO;
import cn.lystudio.rohmtimeopwide_background_v11.entity.po.DepartmentsPO;
import cn.lystudio.rohmtimeopwide_background_v11.entity.po.MachinePO;
import cn.lystudio.rohmtimeopwide_background_v11.entity.po.PlanOutputPO;
import cn.lystudio.rohmtimeopwide_background_v11.mapper.PlanOutputPOMapper;
import cn.lystudio.rohmtimeopwide_background_v11.service.MachineService;
import cn.lystudio.rohmtimeopwide_background_v11.service.PlanOutputService;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;

@Service
@Slf4j
@DS("master")

public class PlanOutputServiceImpl implements PlanOutputService {
    @Resource
    private PlanOutputPOMapper planOutputPOMapper;
    private MachineService machineService;

    @Lazy
    @Autowired
    public void setMachineService(MachineService machineService) {
        this.machineService = machineService;
    }

    /**
     * 鉴权,获取所有计划产量,制造工程,设备
     */
    @Override
    public List<PlanOutputDTO> getAll(String keyword) {
        List<MachineDTO> machineDTOList = machineService.getAll(null);
        // 1.1 过滤machine.enabled=true数据
        CollUtil.filter(machineDTOList, machineDTO -> {
            return machineDTO.getMachine().getEnabled();
        });
        if (CollUtil.isEmpty(machineDTOList)) return null;
        // 1.2.组装 secDeptIDList和 machineNoList
        Set<Integer> secDeptIDList = new ConcurrentHashSet<>();
        Set<DepartmentsPO> secDeptList = new ConcurrentHashSet<>();
        Set<String> machineNoList = new ConcurrentHashSet<>();
        CollUtil.forEach(machineDTOList.iterator(), (machineDTO, index) -> {
            secDeptIDList.add(machineDTO.getSecDept().getDepartmentID());
            secDeptList.add(machineDTO.getSecDept());
            machineNoList.add(machineDTO.getMachine().getMachineNo());
        });
        if (CollUtil.isEmpty(secDeptIDList) || CollUtil.isEmpty(machineNoList) || CollUtil.isEmpty(secDeptList))
            return null;
        // 2.获取所有计划产量
        LambdaQueryWrapper<PlanOutputPO> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(PlanOutputPO::getSecDeptID, secDeptIDList)
                .or()
                .in(PlanOutputPO::getBelong2MacNo, machineNoList)
            .orderByAsc(PlanOutputPO::getBelong2MacNo);
        List<PlanOutputPO> planOutputPOList = planOutputPOMapper.selectList(wrapper);
        if (CollUtil.isEmpty(planOutputPOList)) return null;
        //4.组装view层数据
        List<PlanOutputDTO> planOutputDTOList = CollUtil.list(false);
        CollUtil.forEach(planOutputPOList.iterator(), (planOutput, index) -> {
            PlanOutputDTO planOutputDTO = new PlanOutputDTO();
            planOutputDTO.setPlanOutput(planOutput);
            planOutputDTO.setSecDept(
                    CollUtil.findOne(secDeptList, secDept -> secDept.getDepartmentID().equals(planOutput.getSecDeptID()))
            );
            if (StrUtil.isNotEmpty(planOutput.getBelong2MacNo())) {
                planOutputDTO.setMachine(
                        CollUtil.findOne(machineDTOList, machineDTO -> machineDTO.getMachine().getMachineNo().equals(planOutput.getBelong2MacNo()))
                );
            }
            planOutputDTOList.add(planOutputDTO);
        });

        //5.过滤数据
        CollUtil.removeNull(planOutputDTOList);
        CollUtil.filter(planOutputDTOList, planOutputDTO -> {
            return (ObjectUtil.isNotEmpty(planOutputDTO.getSecDept()));
        });

        //6.搜索过滤
        CollUtil.filter(planOutputDTOList, planOutputDTO -> {

            return (planOutputDTO.getSecDept().getDepartmentName().contains(keyword) );
        });

        return planOutputDTOList;
    }

    @Override
    public int uptPlanOutputEnabled(Integer planOutputID, Boolean enabled) {
        PlanOutputPO planOutputPO = new PlanOutputPO();
        planOutputPO.setPlanOutputID(planOutputID);
        planOutputPO.setEnabled(enabled);

        return planOutputPOMapper.updateById(planOutputPO);
    }

    @Override
    public int delPlanOutput(Integer planOutputID) {
        return planOutputPOMapper.deleteById(planOutputID);
    }

    @Override
    public int addPlanOutput(PlanOutputPO planOutputPO) {
        return planOutputPOMapper.insert(planOutputPO);
    }

    @Override
    public int uptPlanOutput(PlanOutputPO planOutputPO) {
        return planOutputPOMapper.updateById(planOutputPO);
    }

    @Override
    public PlanOutputPO getPlanOutput(String machineNo, Integer dayOrNight) {
        LambdaQueryWrapper<PlanOutputPO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PlanOutputPO::getBelong2MacNo, machineNo)
                .eq(PlanOutputPO::getDayOrNight, dayOrNight)
                .last("limit 1");
        PlanOutputPO planOutputPO = planOutputPOMapper.selectOne(wrapper);
        if (ObjectUtil.isNotEmpty(planOutputPO)) return planOutputPO;
        // 如果通过设备号定位不到设定值,那么需要通过制造工程号定位
        MachinePO machine = machineService.getMachineByMachineNo(machineNo);
        if(ObjectUtil.isEmpty(machine)) return null;
        LambdaQueryWrapper<PlanOutputPO> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(PlanOutputPO::getSecDeptID, machine.getSecDeptID())
                .eq(PlanOutputPO::getDayOrNight, dayOrNight)
                .last("limit 1");
        PlanOutputPO planOutputPO1 = planOutputPOMapper.selectOne(wrapper1);
        return planOutputPO1;
    }
}
